package redis

import (
	"fmt"
	"gitee.com/go-web-2/web_framework/context"
	"gitee.com/go-web-2/web_framework/session"
	"time"
)

type Store struct {
	prefix   string
	duration time.Duration
	cmd      redis.Cmdable
}

func (r *Store) Generate(ctx *context.Context, id string) (session.Session, error) {
	key := r.getRedisKey(id)
	_, err := r.cmd.HSet(ctx.R.Context(), key, id, id).Result()
	if err != nil {
		return nil, err
	}
	_, err = r.cmd.Expire(ctx.R.Context(), key, r.duration).Result()
	if err != nil {
		return nil, err
	}
	return &Session{
		cmd:      r.cmd,
		redisKey: key,
		id:       id,
	}, nil
}

func (r *Store) Get(ctx *context.Context, id string) (session.Session, error) {
	key := r.getRedisKey(id)
	cnt, err := r.cmd.Exists(ctx.R.Context(), key).Result()
	if err != nil {
		return nil, err
	}
	if cnt == 0 {
		return nil, fmt.Errorf("session %s 未找到", id)
	}
	return &Session{
		cmd:      r.cmd,
		redisKey: key,
		id:       id,
	}, nil
}

func (r *Store) Remove(ctx *context.Context, id string) error {
	key := r.getRedisKey(id)
	_, err := r.cmd.Del(ctx.R.Context(), key).Result()
	return err
}

func (r *Store) Refresh(ctx *context.Context, id string) error {
	key := r.getRedisKey(id)
	_, err := r.cmd.Expire(ctx.R.Context(), key, r.duration).Result()
	return err
}

func (r *Store) getRedisKey(id string) string {
	return fmt.Sprintf("%s-%s", r.prefix, id)
}

func NewRedisStore(cmd redis.Cmdable, prefix string, duration time.Duration) *Store {
	return &Store{
		prefix:   prefix,
		duration: duration,
		cmd:      cmd,
	}
}
